package com.jason.system.common.shiro;

import com.jason.system.common.filter.JwtFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author jie
 * @version 1.0
 * success come from self-discipline
 * @date 2021/3/19 12:49
 */

@Configuration
public class ShiroConfig {
  /*
   * SecurityManager,安全管理器,所有与安全相关的操作都会与之进行交互;
   * 它管理着所有Subject,所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager
   * DefaultWebSecurityManager :
   * 会创建默认的DefaultSubjectDAO(它又会默认创建DefaultSessionStorageEvaluator)
   * 会默认创建DefaultWebSubjectFactory
   * 会默认创建ModularRealmAuthenticator
   */

  /**
   * 添加注解支持
   * @return LifecycleBeanPostProcessor
   */
  @Bean
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
    return new LifecycleBeanPostProcessor();
  }

  /**
   * 开启注解
   * @return DefaultAdvisorAutoProxyCreator
   */
  @Bean
  @DependsOn("lifecycleBeanPostProcessor")
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
    DefaultAdvisorAutoProxyCreator defaultAap = new DefaultAdvisorAutoProxyCreator();
    defaultAap.setProxyTargetClass(true);
    return defaultAap;
  }

  @Bean
  public DefaultWebSecurityManager  securityManager(){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 设置realms
    securityManager.setRealm(shiroRealm());
    // close session
    DefaultSubjectDAO defaultSubjectDAO = (DefaultSubjectDAO) securityManager.getSubjectDAO();
    DefaultSessionStorageEvaluator evaluator = (DefaultSessionStorageEvaluator) defaultSubjectDAO.getSessionStorageEvaluator();
    evaluator.setSessionStorageEnabled(Boolean.FALSE);
    defaultSubjectDAO.setSessionStorageEvaluator(evaluator);
    return securityManager;
  }

  /**
   * 将自己的验证方式加入容器
   * @return ShiroRealm
   */
  @Bean
  @DependsOn("lifecycleBeanPostProcessor")
  public ShiroRealm shiroRealm(){
    return new ShiroRealm();
  }

  /**
   * Filter工厂，设置对应的过滤条件和跳转条件
   * @param securityManager
   * @return ShiroFilterFactoryBean
   */
  @Bean
  public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    Map<String, Filter> filterMap = new HashMap<>();
    //登出
    filterMap.put("jwt", new JwtFilter());
    shiroFilterFactoryBean.setFilters(filterMap);
    shiroFilterFactoryBean.setSecurityManager(securityManager);

    Map<String, String> filterRuleMap = new HashMap<>(8);
    //登陆相关api不需要被过滤器拦截
    filterRuleMap.put("/api/user/login/**", "anon");
    filterRuleMap.put("/api/user/register/**", "anon");
    filterRuleMap.put("/api/unauthorized", "anon");
    // 所有请求通过JWT Filter
    filterRuleMap.put("/**", "jwt");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterRuleMap);
    return shiroFilterFactoryBean;
  }
}
